home *** CD-ROM | disk | FTP | other *** search
/ Deutsche Edition 1 / Deutsche Edition 1.iso / amok / amok_lha / amok82.lha / Mini / txt / Parser.mod < prev    next >
Text File  |  1993-08-15  |  3KB  |  87 lines

  1. MODULE Parser;
  2.  
  3. IMPORT S := Scanner, R := Requests, Code;
  4.  
  5. PROCEDURE Chk(sym: INTEGER; msg: ARRAY OF CHAR);
  6. BEGIN IF S.sym=sym THEN S.GetSym ELSE R.Fail(msg) END END Chk;
  7.  
  8. PROCEDURE VarDeclaration;
  9. (* VarDeclaration -> VAR Identifier {"," Identifier} . *)
  10. BEGIN
  11.   REPEAT
  12.     S.GetSym;
  13.     IF S.sym#S.ident THEN R.Fail("Bezeichner in erwartet!") END;
  14.     Code.DCL(S.identifier);
  15.     S.GetSym;
  16.   UNTIL S.sym#S.comma;
  17. END VarDeclaration;
  18.  
  19. PROCEDURE Factor;
  20. (* Factor         -> Identifier | Constant . *)
  21. BEGIN
  22.   CASE S.sym OF
  23.   | S.ident : Code.MOVEvarD0  (S.identifier); S.GetSym;
  24.   | S.const : Code.MOVEconstD0(S.constant  ); S.GetSym;
  25.   ELSE R.Fail("Faktor erwartet") END;
  26. END Factor;
  27.  
  28. PROCEDURE Expression;
  29. (* Expression     -> [ "+" | "-" ] Factor { ( "+" | "-" ) Factor } . *)
  30. VAR neg: BOOLEAN;   (* muß D0 negiert werden? *)
  31. BEGIN
  32.   neg := FALSE;
  33.   IF S.sym IN {S.plus,S.minus} THEN neg := S.sym=S.minus; S.GetSym END;
  34.   Factor;
  35.   IF neg THEN Code.NEGD0 END;
  36.   WHILE S.sym IN {S.plus,S.minus} DO
  37.     neg := S.sym=S.minus; S.GetSym;
  38.     Code.MOVED0D1;
  39.     Factor;
  40.     IF neg THEN Code.NEGD0 END;
  41.     Code.ADDD1D0;
  42.   END;
  43. END Expression;
  44.  
  45. PROCEDURE Statement;
  46. (* Statement      -> Assignment | While | Print .            *)
  47. (* Assignment     -> Identifer "=" Expression .              *)
  48. (* While          -> WHILE Expression DO { Statement } END . *)
  49. (* Print          -> PRINT Expression                        *)
  50. VAR
  51.   varname: S.Identifier;                      (* Ziel einer Zuweisung *)
  52.   start,end : INTEGER;                   (* Labels bei einer Schleife *)
  53. BEGIN
  54.   CASE S.sym OF
  55.   | S.ident: varname := S.identifier; S.GetSym;          (* Zuweisung *)
  56.              Chk(S.equal,"'=' erwartet!");
  57.              Expression;
  58.              Code.MOVED0var(varname);
  59.   | S.while: S.GetSym;                                    (* Schleife *)
  60.              start := Code.GetLabel(); end := Code.GetLabel();
  61.              Code.Label(start);
  62.              Expression;
  63.              Chk(S.do,"DO erwartet!");
  64.              Code.TSTD0; Code.BLE(end);
  65.              WHILE S.sym#S.end DO Statement END;
  66.              Chk(S.end,"END erwartet!");
  67.              Code.BRA(start); Code.Label(end);
  68.   | S.print: S.GetSym; Expression; Code.PrintD0;           (* Ausgabe *)
  69.   ELSE R.Fail("Statement erwartet!") END;
  70. END Statement;
  71.  
  72. PROCEDURE Program*;
  73. (* Program -> PROGRAM [ VarDeclaration ] BEGIN { Statement } END. *)
  74. VAR start: INTEGER;
  75. BEGIN
  76.   S.GetSym; Chk(S.program,"PROGRAM erwartet!");
  77.   start := Code.GetLabel(); Code.BRA(start);
  78.   IF S.sym=S.var THEN VarDeclaration END;
  79.   Chk(S.begin,"BEGIN erwartet!");
  80.   Code.StartUp(start);
  81.   WHILE S.sym#S.end DO Statement END;
  82.   Code.CleanUp;
  83.   Chk(S.end,"END erwartet!");
  84. END Program;
  85.  
  86. END Parser.
  87.